//
//  ASyncURLConnection.m
//  MacTestProject
//
//  Created by LiuLichen on 2022/5/17.
//

#import "ASyncURLConnection.h"

@implementation ASyncURLConnection

+ (id) request:(NSString *)requestUrl completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock {
    /**
     * ARC无效时，如以下这样应当用autorelease类方法返回
     *
     * id obj = [[self alloc] initWithRequest:requestUrl completeBlock:completeBlock errorBlock:errorBlock];
     * return [obj autorelease];
     *
     * 因为此方法的方法名不是以alloc/new/copy/mutableCopy开头的，所以ARC有效时，自动地返回注册到autoreleasepool中的对象
     */

    return [[self alloc] initWithRequest:requestUrl completeBlock:completeBlock errorBlock:errorBlock];
}

- (id) initWithRequest:(NSString *)requestUrl completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock {
    NSURL* url = [NSURL URLWithString:requestUrl];
    NSURLRequest* request = [NSURLRequest requestWithURL:url];

    if ((self = [super initWithRequest:request delegate:self startImmediately:NO])) {
        data_ = [[NSMutableData alloc] init];

        // 为了在之后的代码中安全地使用传递到此方法中的Block，调用copy实例方法确保Block被配置在堆上
        completeBlock_ = [completeBlock copy];
        errorBlock_ = [errorBlock copy];

        [self start];
    }

    /**
     * 生成的NSMutableData类对象和copy的Block由附有__strong修饰符的成员变量强引用，处于被持有的状态。
     *
     * 由此如果该对象被废弃，附有__strong修饰符成员变量的强引用也随之失效，NSMutableData类对象和Block自动地释放。
     *
     * 由此dealloc实例方法不用显式实现。
     */
    return self;
}

- (void) connection:(NSURLConnection*)connection
 didReceiveResponse:(NSURLResponse *)response {
    [data_ setLength:0];
}

- (void) connection:(NSURLConnection*)connection
     didReceiveData:(NSData*)data {
    [data_ appendData:data];
}

- (void) connectionDidFinishLoading:(NSURLConnection*)connection {
    // 下载成功时调用用于回调的Block
    completeBlock_(data_);
}

- (void) connection:(NSURLConnection*)connection
   didFailWithError:(NSError *)error {
    // 发生错误时调用用于回调的Block
    errorBlock_(error);
}

@end
